/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.l2jserver.gameserver.events;

import javolution.util.FastList;

import com.l2jserver.Config;
import com.l2jserver.gameserver.Announcements;
import com.l2jserver.gameserver.ThreadPoolManager;
import com.l2jserver.gameserver.datatables.NpcTable;
import com.l2jserver.gameserver.datatables.SpawnTable;
import com.l2jserver.gameserver.model.L2Spawn;
import com.l2jserver.gameserver.model.L2World;
import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
import com.l2jserver.gameserver.templates.chars.L2NpcTemplate;
import com.l2jserver.util.Rnd;

/**
 * @author Laikeriz
 */
public class LMSEvent
{
	public static FastList<Integer> participants = new FastList<Integer>();
	public static LMSState currentState = LMSState.IDLE;
	public static int[] winners = new int[3];
	private static L2Spawn _npcSpawn = null;
	private static L2Npc _lastNpcSpawn = null;
	
	public static enum LMSState
	{
		IDLE, REGISTERING, FIGHTING, REWARDING
	}
	
	public static void init()
	{
		ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new VariousTasks(LMSState.REGISTERING), Config.LMS_INTERVAL * 1000, Config.LMS_INTERVAL * 1000);
	}
	
	public static void handleDisconnect(L2PcInstance player)
	{
		if (currentState == LMSState.REGISTERING || currentState == LMSState.FIGHTING)
		{
			switch (participants.size())
			{
				case 1:
					break;
				case 2:
					winners[1] = player.getObjectId();
					participants.remove(participants.indexOf(player.getObjectId()));
					break;
				case 3:
					winners[2] = player.getObjectId();
					participants.remove(participants.indexOf(player.getObjectId()));
					break;
				default:
					participants.remove(participants.indexOf(player.getObjectId()));
					break;
			}
		}
	}
	
	public static void sendLMSMessage(String text)
	{
		Announcements.getInstance().announceToAll(text);
	}
	
	public static boolean isParticipating(int objId)
	{
		return participants.contains(objId);
	}
	
	public static boolean handleRegistrant(L2PcInstance player, boolean reg)
	{
		if (currentState == LMSState.REGISTERING)
		{
			if (reg)
				if (!participants.contains(player.getObjectId()) && !player.isInOlympiadMode())
					return participants.add(player.getObjectId());
				else if (participants.contains(player.getObjectId()))
					participants.remove(player.getObjectId());
		}
		return false;
	}
	
	public static void handleDie(L2PcInstance player)
	{
		if (currentState != LMSState.FIGHTING)
			return;
		switch (participants.size())
		{
			case 3:
				winners[2] = player.getObjectId();
				participants.remove(participants.indexOf(player.getObjectId()));
				break;
			case 2:
				winners[1] = player.getObjectId();
				participants.remove(participants.indexOf(player.getObjectId()));
				break;
			default:
				participants.remove(participants.indexOf(player.getObjectId()));
				break;
		}
	}
	
	public static void telePlayers(boolean town)
	{
		for (int i : participants)
		{
			L2PcInstance player = null;
			player = L2World.getInstance().getPlayer(i);
			if (player == null)
			{
				participants.remove(i);
				continue;
			}
			if (!town)
			{
				player.teleToLocation(Integer.parseInt(Config.LMS_COORDS.split(",")[0]) + Rnd.get(-200, 200), Integer.parseInt(Config.LMS_COORDS.split(",")[1]) + Rnd.get(-200, 200), Integer.parseInt(Config.LMS_COORDS.split(",")[2] + 50));
				player.setIsParalyzed(true);
			}
			else
				player.teleToLocation(_lastNpcSpawn.getX(), _lastNpcSpawn.getY(), _lastNpcSpawn.getZ());
			player.stopAllEffects();
			
		}
	}
	
	public static void unparaPlayers()
	{
		for (int i : participants)
		{
			L2PcInstance player = null;
			player = L2World.getInstance().getPlayer(i);
			if (player == null)
			{
				participants.remove(i);
				continue;
			}
			player.setIsParalyzed(false);
		}
	}
	
	public static boolean rewardWinners()
	{
		if (winners[1] == 0 || winners[2] == 0)
			return false;
		
		for (int i = 0; i <= 2; i++)
		{
			L2PcInstance player = null;
			sendLMSMessage("LMS event winners are:");
			switch (i)
			{
				case 0:
					player = L2World.getInstance().getPlayer(participants.get(0));
					if (participants.get(0) == 0 || participants.get(0) == null || player == null)
					{
						sendLMSMessage("1st place winner was offline so he haven't got any reward");
						break;
					}
					if (Config.LMS_1ST_REWARD != "" && Config.LMS_1ST_REWARD != null)
						for (String a : Config.LMS_1ST_REWARD.split(";"))
							if (a != "" && a != null)
								player.addItem("LMS", Integer.parseInt(a.split(",")[0]), Integer.parseInt(a.split(",")[1]), null, true);
					sendLMSMessage("1st place: " + player.getName());
					break;
				case 1:
					player = L2World.getInstance().getPlayer(winners[1]);
					if (winners[1] == 0 || player == null)
					{
						sendLMSMessage("2nd place winner was offline so he haven't got any reward");
						break;
					}
					if (Config.LMS_2ND_REWARD != "" && Config.LMS_2ND_REWARD != null)
						for (String a : Config.LMS_2ND_REWARD.split(";"))
							if (a != "" && a != null)
								player.addItem("LMS", Integer.parseInt(a.split(",")[0]), Integer.parseInt(a.split(",")[1]), null, true);
					sendLMSMessage("2nd place: " + player.getName());
					break;
				case 2:
					player = L2World.getInstance().getPlayer(winners[2]);
					if (winners[2] == 0 || player == null)
					{
						sendLMSMessage("3rd place winner was offline so he haven't got any reward");
						break;
					}
					if (Config.LMS_3RD_REWARD != "" && Config.LMS_3RD_REWARD != null)
						for (String a : Config.LMS_3RD_REWARD.split(";"))
							if (a != "" && a != null)
								player.addItem("LMS", Integer.parseInt(a.split(",")[0]), Integer.parseInt(a.split(",")[1]), null, true);
					sendLMSMessage("3rd place: " + player.getName());
					break;
			}
		}
		return true;
	}
	
	public static class VariousTasks implements Runnable
	{
		LMSState _state;
		
		public VariousTasks(LMSState state)
		{
			_state = state;
		}
		
		public void run()
		{
			currentState = _state;
			switch (_state.ordinal())
			{
				case 0:
					sendLMSMessage("LMS Event has ended");
					if (_lastNpcSpawn != null)
						_lastNpcSpawn.deleteMe();
					break;
				case 1:
					sendLMSMessage("Registration to LMS event has begun");
					L2NpcTemplate tmpl = NpcTable.getInstance().getTemplate(Config.LMS_NPC_ID);
					try
					{
						_npcSpawn = new L2Spawn(tmpl);
						_npcSpawn.setLocx(Config.LMS_NPC_COORDS[0]);
						_npcSpawn.setLocy(Config.LMS_NPC_COORDS[1]);
						_npcSpawn.setLocz(Config.LMS_NPC_COORDS[2]);
						_npcSpawn.setAmount(1);
						_npcSpawn.setHeading(Config.LMS_NPC_COORDS[2]);
						_npcSpawn.setRespawnDelay(1);
						SpawnTable.getInstance().addNewSpawn(_npcSpawn, false);
						_npcSpawn.init();
						_lastNpcSpawn = _npcSpawn.getLastSpawn();
						_lastNpcSpawn.setCurrentHp(_lastNpcSpawn.getMaxHp());
						_lastNpcSpawn.setTitle("TvT Event Participation");
						_lastNpcSpawn.isAggressive();
						_lastNpcSpawn.decayMe();
						_lastNpcSpawn.spawnMe(_npcSpawn.getLastSpawn().getX(), _npcSpawn.getLastSpawn().getY(), _npcSpawn.getLastSpawn().getZ());
						_lastNpcSpawn.broadcastPacket(new MagicSkillUse(_lastNpcSpawn, _lastNpcSpawn, 1034, 1, 1, 1));
					}
					catch (Exception e)
					{
					}
					participants.clear();
					winners = new int[3];
					sendLMSMessage("Registration ends in 10 minutes");
					try
					{
						Thread.sleep(300000);
					}
					catch (InterruptedException e)
					{
					}
					sendLMSMessage("Registration ends in 5 minutes");
					try
					{
						Thread.sleep(120000);
					}
					catch (InterruptedException e)
					{
					}
					sendLMSMessage("Registration ends in 3 minutes");
					try
					{
						Thread.sleep(120000);
					}
					catch (InterruptedException e)
					{
					}
					sendLMSMessage("Registration ends in 1 minute");
					try
					{
						Thread.sleep(30000);
					}
					catch (InterruptedException e)
					{
					}
					sendLMSMessage("Registration ends in 30 seconds");
					try
					{
						Thread.sleep(25000);
					}
					catch (InterruptedException e)
					{
					}
					sendLMSMessage("Registration ends in 5 seconds");
					ThreadPoolManager.getInstance().scheduleGeneral(new VariousTasks(LMSState.FIGHTING), 5000);
					try
					{
						Thread.sleep(2000);
					}
					catch (InterruptedException e)
					{
					}
					sendLMSMessage("Registration ends in 3 seconds");
					try
					{
						Thread.sleep(1000);
					}
					catch (InterruptedException e)
					{
					}
					sendLMSMessage("Registration ends in 2 seconds");
					try
					{
						Thread.sleep(1000);
					}
					catch (InterruptedException e)
					{
					}
					sendLMSMessage("Registration ends in 1 seconds");
					break;
				case 2:
					sendLMSMessage("Registration has ended");
					if (participants.size() <= 3)
					{
						sendLMSMessage("Not enough participants for event to start");
						ThreadPoolManager.getInstance().scheduleGeneral(new VariousTasks(LMSState.IDLE), 5000);
						break;
					}
					sendLMSMessage("Event participants will be teleported to event place in 10 seconds.");
					try
					{
						Thread.sleep(10000);
					}
					catch (InterruptedException e)
					{
					}
					telePlayers(false);
					sendLMSMessage("Teleporting players to event place");
					sendLMSMessage("Battle will begin in 25 seconds");
					try
					{
						Thread.sleep(25000);
					}
					catch (InterruptedException e)
					{
					}
					sendLMSMessage("Battle has begun");
					unparaPlayers();
					int a = 0;
					while (!rewardWinners())
					{
						a += 5000;
						if (a >= 600000)
						{
							sendLMSMessage("10 minutes passed and there were no winners");
							break;
						}
						try
						{
							Thread.sleep(5000);
						}
						catch (InterruptedException e)
						{
						}
					}
					telePlayers(true);
					ThreadPoolManager.getInstance().scheduleGeneral(new VariousTasks(LMSState.IDLE), 5000);
					break;
				case 3:
					sendLMSMessage("Registration to event has ended");
					sendLMSMessage("Teleporting players to event place");
					//telePlayers();
					break;
			}
		}
	}
}
